package org.hxzon.tapestry5.services;

import java.util.Collection;
import java.util.List;

import org.apache.tapestry5.Validator;
import org.apache.tapestry5.ioc.Configuration;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.annotations.Contribute;
import org.apache.tapestry5.ioc.services.Builtin;
import org.apache.tapestry5.ioc.services.CoercionTuple;
import org.apache.tapestry5.ioc.services.ThreadLocale;
import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.services.AssetSource;
import org.apache.tapestry5.services.BeanBlockContribution;
import org.apache.tapestry5.services.BeanBlockSource;
import org.apache.tapestry5.services.ComponentClassResolver;
import org.apache.tapestry5.services.Core;
import org.apache.tapestry5.services.DisplayBlockContribution;
import org.apache.tapestry5.services.LibraryMapping;
import org.hxzon.tapestry5.pages.ExPropertyDisplayBlocks;
import org.hxzon.tapestry5.util.ArrayToListCoercion;
import org.hxzon.tapestry5.util.CollectionToListCoercion;
import org.hxzon.tapestry5.util.StringToCharCoercion;
import org.hxzon.tapestry5.util.TapestryEx;

public class HxzonTapestryModule {
//	public static void contributeComponentClassResolver(Configuration<LibraryMapping> configuration) {
//		configuration.add(new LibraryMapping(TapestryEx.ModulePrefix, "org.hxzon.tapestry5"));
//		configuration.add(new LibraryMapping("app", "org.hxzon.tapestry5"));
//		configuration.add(new LibraryMapping("", "org.hxzon.tapestry5"));
//	}

//	public static void contributeClasspathAssetAliasManager(MappedConfiguration<String, String> configuration) {
//		configuration.override("", "org/hxzon/tapestry5");
//		configuration.override("h", "org/hxzon/tapestry5");
//	}

    @Contribute(ComponentClassResolver.class)
    public static void contributeComponentClassResolver(Configuration<LibraryMapping> configuration) {
        configuration.add(new LibraryMapping(TapestryEx.ModulePrefix, "org.hxzon.tapestry5"));
    }

    @Contribute(BeanBlockSource.class)
    public static void provideDefaultBeanBlocks(Configuration<BeanBlockContribution> configuration) {
        addExDisplayBlock(configuration, TapestryEx.DataType_currency);
        addExDisplayBlock(configuration, TapestryEx.DataType_day);
        addExDisplayBlock(configuration, TapestryEx.DataType_time);
        addExDisplayBlock(configuration, TapestryEx.DataType_daytime);
        addExDisplayBlock(configuration, TapestryEx.DataType_nanotime);
        addExDisplayBlock(configuration, TapestryEx.DataType_html);
    }

    private static void addExDisplayBlock(Configuration<BeanBlockContribution> configuration, String name) {
        configuration.add(new DisplayBlockContribution(name, TapestryEx.ModulePagePrefix + ExPropertyDisplayBlocks.class.getSimpleName(), name));
    }

    @SuppressWarnings("rawtypes")
    public static void contributeFieldValidatorSource(MappedConfiguration<String, Validator> configuration) {
        configuration.override("email", new org.hxzon.tapestry5.validator.Email());
        configuration.override("min", new org.hxzon.tapestry5.validator.Min());
        configuration.override("max", new org.hxzon.tapestry5.validator.Max());
        configuration.add("equal", new org.hxzon.tapestry5.validator.Equal());
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static void contributeTypeCoercer(Configuration<CoercionTuple> configuration, @Builtin TypeCoercer coercer, @Builtin final ThreadLocale threadLocale, @Core final AssetSource assetSource) {
        configuration.add(new CoercionTuple(Collection.class, List.class, new CollectionToListCoercion()));
        configuration.add(new CoercionTuple(Object[].class, List.class, new ArrayToListCoercion()));
        configuration.add(new CoercionTuple(String.class, char.class, new StringToCharCoercion()));
    }
}
